<!doctype html>
<html lang="zh_cn" itemscope itemtype="http://schema.org/Person">
<head>
            <meta charset="utf-8">
        <!-- Site Meta Data -->
        <title>[原创]WebRTC调用摄像头建立聊天室</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="description" content="技术博客,涉及Java/PHP/Python/Javascript等,聊聊程序,聊聊生活,聊聊事实,聊聊育儿">
        <meta name="keywords" content="编码经验,技术分享,生活积累,实事评说">
        <meta name="author" content="布丁缘">

        <link rel="shortcut icon" href="">

        <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,700' rel='stylesheet' type='text/css'>
        <!-- Style Meta Data -->
        <link rel="stylesheet" href="https://www.ddkiss.com/theme/css/style.css" type="text/css"/>
        <link rel="stylesheet" href="https://www.ddkiss.com/theme/css/pygments.css" type="text/css"/>

        <!-- Feed Meta Data -->
            <link href="https://www.ddkiss.com/feeds/all.atom.xml" type="application/atom+xml" rel="alternate"
                  title="一个程序员的简单生活 ATOM Feed"/>


    <meta name="keywords" content="">
    <link rel="stylesheet" href="//dn-coding-net-public-file.qbox.me/Coding-Comments/v0.1.0/default.css">
</head>

<body>
<!-- Sidebar -->
<aside>
    <center><h1><a href="/" style="color:#fff"><img id="avatar" src="/images/avatar.jpg"></a></h1></center>
        <p>一个程序员的简单生活</p>
    <br>
    <nav class="nav">
        <ul class="list-bare">
                <li><a class="nav__link" href="https://www.ddkiss.com/category/chang-yong-ji-qiao.html">常用技巧</a></li>
                <li><a class="nav__link" href="https://www.ddkiss.com/category/kai-fa-huan-jing.html">开发环境</a></li>
                <li><a class="nav__link" href="https://www.ddkiss.com/category/sheng-huo-dian-di.html">生活点滴</a></li>

                <li><a class="nav__link" href="/pages/books.html">书单</a></li>
                <li><a class="nav__link" href="/pages/movies.html">影单</a></li>
                <li><a class="nav__link" href="/pages/downloads.html">下载</a></li>
                <li><a class="nav__link" href="/pages/about.html">关于我</a></li>


        </ul>
    </nav>


    <form>
      <input type="text"  id="bdcsMain"/>
    </form>

</aside>

<!-- Content -->
<article>
  <main>
    <nav>
      <a href="/">首页</a>
      <a href="/archives.html">归档</a>
      <a href="/categories.html">分类</a>
      <a href="/tags.html">标签</a>
      <a href="/pages/about.html">关于我</a>
    </nav>
  </main>
    <section id="content">
        <article>
            <h2 class="post_title post_detail"><a href="https://www.ddkiss.com/archives/5.html" rel="bookmark"
                                                  title="Permalink to [原创]WebRTC调用摄像头建立聊天室">[原创]WebRTC调用摄像头建立聊天室</a></h2>

            <div class="post_list">
                <span>作者：</span><a href="https://www.ddkiss.com/author/bu-ding-yuan.html">布丁缘</a>
                <span class="post_category">分类：<a href="https://www.ddkiss.com/category/kai-fa-huan-jing.html" rel="bookmark"
                                               title="Permalink to 开发环境">开发环境</a></span>
                <span class="post_date">  时间：2017-09-24 16:03:00</span>

            </div>
            <div class="entry-content blog-post">
                <h1>前言</h1>
<p>最近在思考，腾讯ＱＱ或微信的视频聊天是怎么实现的？点对点的视频是否需要足够的带宽支持？实现的原理是怎么样的呢？后来发现了webrtc这个东东。测试后发现，需要安装coturn来实现打洞。所以，就有了本文.</p>
<h1>安装turnserver</h1>
<ol>
<li>
<p>下载<a href="https://github.com/coturn/coturn/wiki/Downloads">coturn</a></p>
</li>
<li>
<p>有turnserver-4.5.0.6-CentOS7.2-x86_64.tar.gz版，但是下载执行安装后，死活因为mysql的包冲突(我装的是5.7)，提示缺少lib</p>
</li>
<li>
<p>下载了源码，turnserver-4.5.0.6.tar.gz，安装后，虽然提示安装不成功，但无所谓，因为可以用默认的sqlite。</p>
</li>
</ol>
<h1>配置</h1>
<p>此处是坑最多的地方，网上的那些教程都没有正在线上跑过，所以都不行。我也是试了很久，最后老老实实看官网的说明配置成功了。即使是像阿里云ECS这种只有有专线网络都可以，即使是在子网里。参考<a href="https://github.com/coturn/coturn/wiki/turnserver#webrtc-usage">turnserver-webrtc-usage</a>, 提到的重要的几点</p>
<ol>
<li>
<p>必须用 long-term credentials, 所以启动参数里必须带 -a</p>
</li>
<li>
<p>Webrtc禁止匿名访问，所以必须设置用户名密码，或者realm生成的key</p>
</li>
<li>
<p>可以输出信息，启动参数里带上　-v -f</p>
</li>
<li>
<p>最重要最重要的一点，如果需要NAT内网穿透，则必须用 -X 参数，比如" -X 19.1.1.1 "</p>
</li>
<li>
<p>限制响应端口号范围，用 --min-port 和 --max-port 参数</p>
</li>
</ol>
<p>所以最终步骤为：</p>
<p>1)  生成key</p>
<div class="highlight"><pre><span></span>[root@myos sqlite]# turnadmin -k -u sa -r dd -p wh

0xb46bcdfee2d73d6d311f634a7f0903
</pre></div>


<p>2)  启动 turnserver</p>
<div class="highlight"><pre><span></span>[root@myos software]# turnserver -a  -b -v -u sa:0xb46bcdfee2d73d6d311f634a7f0903 -r dd -X 106.0.0.1 -f
</pre></div>


<p>3)  检测turn服务是否正常</p>
<div class="highlight"><pre><span></span>[root@myos sqlite]# turnutils_uclient -u sa -w wh  106.0.0.16

0: Total connect time is 0

1: start_mclient: msz=2, tot_send_msgs=0, tot_recv_msgs=0, tot_send_bytes ~ 0, tot_recv_bytes ~ 0

2: start_mclient: msz=2, tot_send_msgs=0, tot_recv_msgs=0, tot_send_bytes ~ 0, tot_recv_bytes ~ 0
</pre></div>


<p>4) 检测stun服务是否正常</p>
<div class="highlight"><pre><span></span>[root@myos sqlite]# turnutils_stunclient -p 3478 106.0.0.16

0: IPv4. UDP reflexive addr: 106.0.0.16:53088
</pre></div>


<h1>开发信令服务器</h1>
<p>Webrtc发布到线上必须采用https协议，所以参考node express 如何配置https</p>
<h1>从Webrtc到EasyRtc</h1>
<p>从<a href="https://segmentfault.com/a/1190000000439103">webrtc搭建聊天室</a>到<a href="http://www.cnblogs.com/lingyunhu/p/3621057.html">Android WebRTC 音视频开发总结（三）-- 信令服务和媒体服务</a> ,然后发现了EasyRtc, 对webrtc进行了一层封装。比自己实现信令要简单一点吧。从easyrtc的官方介绍中提到，局域网内大概可以支持14个peer，但是互联网上大概3个peer就会出现卡顿现象(<a href="https://www.easyrtc.com/docs/easyrtc_gettingStarted.php#scaling-up">We've seen a 640x480 video successfully shared to 14 peers when all parties are on the same local network, but struggle with 3 peers when the peers were spread across the internet. The user observed effect is that the frame rate gets low, the picture gets grainy and pixelated, sound gets choppy, and connections can get dropped.</a>)</p>
<h1>参考</h1>
<ol>
<li>
<p><a href="https://segmentfault.com/a/1190000000436544">WebRTC搭建视频聊天室</a></p>
</li>
<li>
<p><a href="https://github.com/LingyuCoder/SkyRTC-demo">聊天室git</a></p>
</li>
<li>
<p><a href="http://www.cnblogs.com/wunaozai/p/5520084.html">聊天室改进</a></p>
</li>
<li>
<p><a href="http://blog.csdn.net/qq_32903893/article/details/53811935">HTTPS实现websocket</a></p>
</li>
<li>
<p><a href="http://www.expressjs.com.cn/">基于Node.js实现的web开发框架</a></p>
</li>
<li>
<p><a href="http://www.jianshu.com/p/853099ae2edd">基于Nodejs和Express创建的服务器</a></p>
</li>
<li>
<p><a href="https://www.wilddog.com/product/webrtc-demo/join">商业化产品</a></p>
</li>
<li>
<p><a href="https://github.com/EricssonResearch/openwebrtc-examples/blob/master/web/client/main.js">完整demo</a></p>
</li>
<li>
<p><a href="https://yq.aliyun.com/articles/138462">阿里云建立turn服务</a></p>
</li>
<li>
<p><a href="http://blog.csdn.net/u012908515/article/details/54863661">coturn安装</a></p>
</li>
<li>
<p><a href="https://github.com/coturn/coturn/wiki/turnadmin">turnadmin</a></p>
</li>
</ol>
<h1>总结</h1>
<p>webrtc利用websoket协议可以实现点对点的通讯，传输视频、文件等都可以。需要注意的一点是，如果发布到线上，则必须使用https协议。经过测试，多余３个的peer，其实效果不好。也就是说，这种方式不太适合做聊天室，而更适合类似QQ的点对点视频。</p>
            </div>
            <div class="post_list">
              <div><span>Tags : </span>
              </div>
            </div>
        </article>
        <div id="container"></div>
        <script type="text/javascript" src="//dn-coding-net-public-file.qbox.me/Coding-Comments/v0.1.0/gitment.min.js"></script>
        <script>
            var gitment = new Gitment({
              owner: 'whusl',
              repo: 'BlogComments',
              oauth: {
                client_id: '621866266817529fba46681653017809',
                client_secret: '14188411740b12ae52159cee9b586bf85cd54125',
              },
            })
            document.getElementById('container').appendChild(gitment.render())
          </script>
    </section>
</article>

<!-- Footer -->
    <footer>
        <p> &copy;2017-2020&nbsp;<a href="http://www.miitbeian.gov.cn/" target="_blank">鄂ICP备17020200号</a>
          Blog powered by <a href="http://getpelican.com/">Pelican</a>
        </p>
    </footer>

    <!-- Analytics -->
    <script>
      var _hmt = _hmt || [];
      (function() {
        var hm = document.createElement("script");
        hm.src = "https://hm.baidu.com/hm.js?88c55edaf311dbacac56a16316b04c8b";
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(hm, s);
      })();
    </script>

<script type="text/javascript">(function(){document.write(unescape('%3Cdiv id="bdcs"%3E%3C/div%3E'));var bdcs = document.createElement('script');bdcs.type = 'text/javascript';bdcs.async = true;bdcs.src = 'http://znsv.baidu.com/customer_search/api/js?sid=14490611060029767912' + '&plate_url=' + encodeURIComponent(window.location.href) + '&t=' + Math.ceil(new Date()/3600000);var s = document.getElementsByTagName('script')[0];s.parentNode.insertBefore(bdcs, s);})();</script>

</body>
</html>